#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define NUM_CARDS 5
#define NUM_SUITS 4
#define NUM_RANKS 13

/* external variables */
bool straight, flush, four, three;
int pairs; /* can be 0, 1 or 2 */

/* prototypes */
void read_cards(int hand[][2]);
void analyze_hand(int hand[][2]);
void print_result(void);
bool card_duplicate(int hand[][2], int rank, int suit);

int main(void)
{
    int hand[NUM_CARDS][2];

    for (;;)
    {
        read_cards(hand);
        analyze_hand(hand);
        print_result();
    }
}

void read_cards(int hand[][2])
{
    char c, rank_ch, suit_ch;
    int rank, suit;
    bool bad_card;
    int cards_read = 0;

    for (int i = 0; i < NUM_CARDS; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            hand[i][j] = -1;
        }
    }

    while (cards_read < NUM_CARDS)
    {
        bad_card = false;
        printf("Enter a card: ");

        rank_ch = getchar();
        switch (rank_ch)
        {
        case '0':
            exit(EXIT_SUCCESS);
        case '2':
            rank = 0;
            break;
        case '3':
            rank = 1;
            break;
        case '4':
            rank = 2;
            break;
        case '5':
            rank = 3;
            break;
        case '6':
            rank = 4;
            break;
        case '7':
            rank = 5;
            break;
        case '8':
            rank = 6;
            break;
        case '9':
            rank = 7;
            break;
        case 't':
        case 'T':
            rank = 8;
            break;
        case 'j':
        case 'J':
            rank = 9;
            break;
        case 'q':
        case 'Q':
            rank = 10;
            break;
        case 'k':
        case 'K':
            rank = 11;
            break;
        case 'a':
        case 'A':
            rank = 12;
            break;
        default:
            bad_card = true;
        }

        suit_ch = getchar();
        switch (suit_ch)
        {
        case 'c':
        case 'C':
            suit = 0;
            break;
        case 'd':
        case 'D':
            suit = 1;
            break;
        case 'h':
        case 'H':
            suit = 2;
            break;
        case 's':
        case 'S':
            suit = 3;
            break;
        default:
            bad_card = true;
        }

        while ((c = getchar()) != '\n')
            if (c != ' ')
                bad_card = true;

        if (bad_card)
            printf("Bad card; ignored.\n");
        else if (card_duplicate(hand, rank, suit))
            printf("Duplicate card; ignored.\n");
        else
        {
            hand[cards_read][0] = rank;
            hand[cards_read][1] = suit;

            cards_read++;
        }
    }
}

void analyze_hand(int hand[][2])
{
    straight = true;
    flush = true;
    four = false;
    three = false;
    pairs = 0;

    // selection sort
    int min_index, min_value, tmp_rank, tmp_suit;
    for (int i = 0; i < NUM_CARDS; i++)
    {
        min_index = i;
        min_value = hand[min_index][0];

        for (int j = i + 1; j < NUM_CARDS; j++)
        {
            if (hand[j][0] < min_value)
                min_index = j;
        }

        // swap min to first element
        tmp_rank = hand[min_index][0];
        tmp_suit = hand[min_index][1];
        hand[min_index][0] = hand[i][0];
        hand[min_index][1] = hand[i][1];
        hand[i][0] = tmp_rank;
        hand[i][1] = tmp_suit;
    }

    /* checks for flush */
    for (int i = 0; i < NUM_CARDS - 1; i++) {
        if (hand[i][1] != hand[i + 1][1]) {
            flush = false;
            break;
        }
    }

    /* checks for straight */
    for (int i = 1; i < NUM_CARDS; i++)
    {
        if (hand[i][0] != hand[i - 1][0] + 1)
        {
            straight = false;
            break;
        }
    }

    /* check for 4-of-a-ind, 3-of-a-kind and pairs */
    int match = 0;
    for (int i = 0; i < NUM_CARDS; i++)
    {
        match = 0;
        for (int j = i + 1; j < NUM_CARDS; j++)
        {
            if (hand[j][0] == hand[i][0])
            {
                match++;
            }

            if (match == 1)
                pairs++;
            if (match == 2)
                three = true;
            if (match == 3)
                four = true;
        }
    }
}

void print_result(void)
{
    if (straight && flush)
        printf("Straight flush");
    else if (four)
        printf("Four of a kind");
    else if (three && pairs == 1)
        printf("Full house");
    else if (flush)
        printf("Flush");
    else if (straight)
        printf("Straight");
    else if (three)
        printf("Three of a kind");
    else if (pairs == 2)
        printf("Two pairs");
    else if (pairs == 1)
        printf("Pair");
    else
        printf("High card");

    printf("\n\n");
}

bool card_duplicate(int hand[][2], int rank, int suit)
{
    for (int i = 0; i < NUM_CARDS; i++)
    {
        if (hand[i][0] == rank && hand[i][1] == suit)
            return true;
    }
    return false;
}